#ifndef QP_QACTIVE_HPP
#define QP_QACTIVE_HPP

#include <pthread.h>
#include "QEQueue.hpp"
#include "QHsm.hpp"

namespace QP {

class QActive : public QHsm {
 public:
  QActive(QStateHandler const initial, bool canCallJava = false);

  virtual void start(uint8_t const prio, std::shared_ptr<const QEvt> qSto[],
                     uint32_t const qLen,
                     std::shared_ptr<const QEvt> ie = nullptr);

  //! Posts an event @p e directly to the event queue of the active
  //! object @p me using the First-In-First-Out (FIFO) policy.
  void postFIFO(const std::shared_ptr<const QEvt>& e);
  //! Posts an event directly to the event queue of the active object
  //! using the Last-In-First-Out (LIFO) policy.
  void postLIFO(const std::shared_ptr<const QEvt>& e);
  //! Un-subscribes from the delivery of all signals to the active object.
  void unsubscribeAll(void) const;
  //! Stops execution of an active object and removes it from the
  //! framework's supervision.
  void stop(void);
  //! Subscribes for delivery of signal @p sig to the active object
  void subscribe(int sig) const;
  //! Un-subscribes from the delivery of signal @p sig to the active object.
  void unsubscribe(int sig) const;

  void defer(QEQueue* const eq, const std::shared_ptr<const QEvt>& e) const;
  bool recall(QEQueue* const eq);

  bool canCallJava() const { return m_canCallJava; }
  virtual void javaAttachThread() {}
  virtual void javaDetachThread() {}

  std::shared_ptr<const QEvt> get_();

 public:
  QEQueue m_eQueue;
  pthread_cond_t m_osObject;
  uint8_t m_thread;
  uint_fast8_t m_prio;

 private:
  bool m_canCallJava;
};

#define POST(e_, dummy_) postFIFO(e_)
}

#endif  // QP_QACTIVE_HPP